package com.sxt.servlet;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.sxt.common.CodeMsg;
import com.sxt.common.Constant;
import com.sxt.common.Result;
import com.sxt.pojo.User;
import com.sxt.service.IUserService;
import com.sxt.service.impl.UserServiceImpl;
import com.sxt.util.RespUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:
 * @author: Mr.T
 * @date 2020-11-03 11:50
 */
@WebServlet("/user.do")
@MultipartConfig//表示支持文件上传  servlet 才开始支持 3.0
public class UserServlet extends HttpServlet {

    IUserService userService = new UserServiceImpl();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String service = req.getParameter("service");
        try {
            //此时 service 值与方法名相同  则可以根据service找到方法
            Method method = this.getClass().getDeclaredMethod(service,HttpServletRequest.class, HttpServletResponse.class);
            //进行方法调用
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            throw  new RuntimeException("找不到方法:"+service);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理用户登录的请求
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //获取验证码
        String checkCode = req.getParameter("checkCode");
        //校验验证码是否一致
        HttpSession session = req.getSession();
        Object o = session.getAttribute(Constant.CHECK_CODE_KEY);
        if (o == null || !StrUtil.equals(checkCode,o.toString())){
            //验证码错误
            Result rs = new Result(CodeMsg.USER_CHECK_CODE_ERROR);
            RespUtil.writer(rs,resp);
            return;
        }
        //返回业务结果
        Result rs = userService.login(username, password);
        //如果登录是成功的  将用户还要放入到session中
        if (rs.getCode().equals(CodeMsg.SUCCESS.code)){
            Object data = rs.getData();
            //将当前用户放入到session中
            req.getSession().setAttribute(Constant.SESSION_CURRENT_USER_KEY,data);
            rs.setData(null);
        }
        //将业务结果使用JSON格式返回给客户端
        //将对象转化为JSON 输出
        RespUtil.writer(rs,resp);
    }

    /**
     * 查询用户的分页信息
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //页码
        String page = req.getParameter("page");
        //每页显示的数据条数
        String limit = req.getParameter("limit");
        //获取查询的参数
        String realname = req.getParameter("realname");
        String role = req.getParameter("role");
        String deleted = req.getParameter("deleted");
        //查询参数
        Map<String,String> params = new HashMap<>();
        //校验参数 放入查询的容器
        if (StrUtil.isNotBlank(realname)){
            params.put("realname",realname);
        }
        if (StrUtil.isNotBlank(role)){
            params.put("role",role);
        }
        if (StrUtil.isNotBlank(deleted)){
            params.put("deleted",deleted);
        }
        // 获取分页查询的数据
        Result result = userService.queryPage(params, page, limit);
        //将数据返回
        RespUtil.writer(result,resp);
    }

    /**
     * 用户离职
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");
        Result result = userService.delete(id);
        //将数据返回
        RespUtil.writer(result,resp);
    }

    /**
     * 处理重置密码
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void reset(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");
        Result result = userService.reset(id);
        //将数据返回
        RespUtil.writer(result,resp);
    }

    /**
     * 新增用户
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String realname = req.getParameter("realname");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String role = req.getParameter("role");
        Result result = userService.add(username,password,realname,role);
        //将数据返回
        RespUtil.writer(result,resp);
    }

    /**
     * 获取所有的业务员
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getAllSalesman(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Result result = userService.queryAllSalesman();
        //将数据返回
        RespUtil.writer(result,resp);
    }

    /**
     * 用户退出
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void loginOut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.invalidate();//销毁session
        resp.sendRedirect("index.jsp");
    }

    /**
     * 修改密码
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String password = req.getParameter("password");
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute(Constant.SESSION_CURRENT_USER_KEY);
        //校验原始密码和当前密码是否一致
        if (!StrUtil.equals(user.getPassword(),password)){
            Result rs = new Result(CodeMsg.USER_PASSWORD_ERROR);
            RespUtil.writer(rs,resp);
            return;
        }
        Integer userId = user.getId();
        String newPassword = req.getParameter("newPassword");
        Result rs = userService.updatePassword(userId,newPassword);
        session.invalidate();//销毁session
        RespUtil.writer(rs,resp);
    }

    /**
     * 文件上传
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void upload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Part userImg = req.getPart("userImg");
        String contentType = userImg.getContentType();//数据类型
        long size = userImg.getSize();//获取数据的长度
        //输入流  输出流
        //字符流 字节流
        //缓冲流
        //转换流
        //打印流
        //随机访问流
        //内存流
        //InputStream inputStream = userImg.getInputStream();//将数据转化为输入流
        //读  写  输出传输   保存 或者 继续传输
        //userImg.write("D:\\aaaaaaaaaaaaaaaaaaa.jpg");
        String header = userImg.getHeader("Content-Disposition");//获取指定的请求头 包含文件的真实名称
        String name = userImg.getName();
        System.out.println("size:"+size);
        System.out.println("header:"+header);
        //servlet 获取的文件数据
        //将其进行保存 : 文件保存后 需要提供一个可以访问这个文件的网络路径
        //一般文件保存 有专门的文件服务器  FTP文件服务器 fastDFS OSS
        //此时将文件保存在 resources/imgs 文件夹中  物理保存  物理路径
        String realPath = req.getServletContext().getRealPath("resources/imgs");
        //由于用户上传的文件的名称可能出现重复 如果直接使用文件名称 则可能出现覆盖问题  需要为文件重命名
        //form-data; name="userImg"; filename="default.jpg"
        //将物理路径拼接文件的名称 张三 1.jpg   1.jpg
        System.out.println(realPath);
        //为文件创建一个名称
        String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String fileFix = getFileFix(userImg);
        //文件保存的路径 物理磁盘路径
        String absolutPath = realPath + File.separator + fileName + fileFix;
        //文件的访问路径  网络访问路径
        String url = "resources/imgs/"+ fileName + fileFix; //存储的相对路径
        userImg.write(absolutPath);//将文件保存
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute(Constant.SESSION_CURRENT_USER_KEY);
        //数据库中存储访问路径 更新数据库中  用的图片的地址
        Result rs = userService.updateImg(user.getId(),url);
        RespUtil.writer(rs,resp);
    }

    /**
     * 获取文件的后缀 带.
     * @param part
     * @return
     */
    private String getFileFix(Part part){
        //form-data; name="userImg"; filename="default.jpg"
        String header = part.getHeader("Content-Disposition");
        String[] split = header.split(";");
        String fileInfo = split[2].trim();
        int index = fileInfo.lastIndexOf(".");
        return fileInfo.substring(index,fileInfo.length() - 1);
    }

}
